import { API_CONFIG } from '../config/apiConfig';

/**
 * 将Base64字符串转换为二进制数据
 * @param {string} base64 - Base64编码的字符串
 * @returns {Uint8Array} - 转换后的二进制数据
 */
const base64ToBinary = (base64) => {
  // 保留Base64补位字符，确保正确解码
  // 注意：移除补位字符可能导致解码错误，特别是在拼接多个分片时
  
  // 解码Base64字符串为二进制字符串
  const binaryString = atob(base64);
  
  // 创建Uint8Array来存储二进制数据
  const bytes = new Uint8Array(binaryString.length);
  
  // 将二进制字符串转换为Uint8Array
  for (let i = 0; i < binaryString.length; i++) {
    bytes[i] = binaryString.charCodeAt(i);
  }
  
  return bytes;
};


/**
 * 将二进制数据转换为Base64字符串
 * @param {Uint8Array} binary - 二进制数据
 * @returns {string} - Base64编码的字符串
 */
const binaryToBase64 = (binary) => {
  // 将二进制数据转换为字符串
  let binaryString = '';
  for (let i = 0; i < binary.length; i++) {
    binaryString += String.fromCharCode(binary[i]);
  }
  
  // 将二进制字符串编码为Base64
  return btoa(binaryString);
};

/**
 * 获取微信大图片的单个分片数据
 * @param {string} fromUserName - 发送者用户名
 * @param {string|number} msgId - 消息ID
 * @param {string} toUserName - 接收者用户名
 * @param {Object} section - 分片信息
 * @param {number} section.DataLen - 请求的数据长度
 * @param {number} section.StartPos - 起始位置
 * @param {number|null} totalLen - 图片总长度，可选
 * @param {Function|null} statusCallback - 状态回调函数，用于通知下载状态
 * @returns {Promise<Object>} - 返回包含图片分片数据的Promise
 */
export const getMsgBigImg = async (fromUserName, msgId, toUserName, section, totalLen = 0, statusCallback = null) => {
  // 立即返回Promise，允许UI继续渲染
  return new Promise((resolve, reject) => {
    try {
      // 通知图片下载状态
      if (statusCallback) {
        statusCallback('downloading');
      }

      // 使用AbortController实现请求超时控制
      const controller = new AbortController();
      const timeoutId = setTimeout(() => {
        controller.abort();
      }, 5000); // 5秒超时限制

      // 构建请求参数
      const requestParams = {
        CompressType: 0,
        FromUserName: fromUserName,
        MsgId: msgId,
        Section: section,
        ToUserName: toUserName,
        TotalLen: totalLen
      };
      
      // 如果提供了总长度，添加到请求参数中
      // if (totalLen !== null) {
      //   requestParams.TotalLen = totalLen;
      // }

      // 执行异步请求
      (async () => {
        try {
          const response = await fetch(`${API_CONFIG.HOST}/message/GetMsgBigImg?key=${API_CONFIG.KEY}`, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify(requestParams),
            signal: controller.signal // 添加AbortController信号
          });

          // 清除超时定时器
          clearTimeout(timeoutId);

          if (!response.ok) {
            throw new Error(`下载高清图片失败: ${response.status} ${response.statusText}`);
          }

          const result = await response.json();

          // 下载成功，通知UI更新状态
          if (statusCallback) {
            statusCallback('downloaded', result);
          }

          resolve(result);
        } catch (error) {
          // 清除超时定时器
          clearTimeout(timeoutId);

          // 判断是否是超时错误
          if (error.name === 'AbortError') {
            const timeoutError = new Error('请求超时，下载高清图片失败');
            console.error('下载高清图片超时:', timeoutError);

            if (statusCallback) {
              statusCallback('failed', timeoutError);
            }

            reject(timeoutError);
          } else {
            console.error('下载高清图片时出错:', error);

            if (statusCallback) {
              statusCallback('failed', error);
            }

            reject(error);
          }
        }
      })();
    } catch (outerError) {
      console.error('下载高清图片过程中发生错误:', outerError);

      if (statusCallback) {
        statusCallback('failed', outerError);
      }

      reject(outerError);
    }
  });
};

/**
 * 下载完整图片并保存到本地
 * @param {string} fromUserName - 发送者用户名
 * @param {string|number} msgId - 消息ID
 * @param {string} toUserName - 接收者用户名
 * @param {Function|null} statusCallback - 状态回调函数，用于通知下载进度
 * @returns {Promise<Object>} - 返回包含完整图片数据的Promise
 */
export const downloadFullImage = async (fromUserName, msgId, toUserName, statusCallback = null) => {
  try {
    // 通知开始下载
    if (statusCallback) {
      statusCallback('downloading', { progress: 0 });
    }

    // 第一次请求获取总长度信息
    const firstPacket = await getMsgBigImg(fromUserName, msgId, toUserName, {
      DataLen: 61440,
      StartPos: 0
    });
    
    // 验证响应数据
    if (!firstPacket || !firstPacket.Data || firstPacket.Code !== 200) {
      const errorMsg = firstPacket?.Message || '获取图片信息失败';
      throw new Error(errorMsg);
    }

    // 提取图片总长度和计算分包信息
    const totalLen = firstPacket.Data.TotalLen;
    const packetSize = 61440; // 每个分包的大小
    const totalPackets = Math.ceil(totalLen / packetSize);
    
    // 创建一个固定大小的Uint8Array来存储完整图片数据
    // 这样可以确保每个分片数据被放置在正确的位置
    const completeImageData = new Uint8Array(totalLen);
    let receivedLength = 0;
    
    // 处理第一个分包的数据
    if (firstPacket.Data.Data && firstPacket.Data.Data.Buffer) {
      // 将base64转换为二进制数据
      const binaryData = base64ToBinary(firstPacket.Data.Data.Buffer);
      // 将数据复制到正确的位置
      completeImageData.set(binaryData, 0);
      receivedLength += binaryData.length;
      
      // 验证接收到的数据长度
      console.log(`第1/${totalPackets}包: 预期长度=${Math.min(packetSize, totalLen)}, 实际接收=${binaryData.length}`);
    }
    
    // 下载剩余的分包
    for (let i = 1; i < totalPackets; i++) {
      const startPos = i * packetSize;
      const expectedLength = Math.min(packetSize, totalLen - startPos);
      
      // 通知下载进度
      if (statusCallback) {
        const progress = Math.round((i / totalPackets) * 100);
        statusCallback('downloading', { progress });
      }
      
      // 请求下一个分包
      const packet = await getMsgBigImg(fromUserName, msgId, toUserName, {
        DataLen: expectedLength,
        StartPos: startPos
      }, totalLen);
      
      // 验证分包数据
      if (!packet || !packet.Data || packet.Code !== 200) {
        const errorMsg = packet?.Message || `获取图片分包${i+1}/${totalPackets}失败`;
        throw new Error(errorMsg);
      }
      
      // 处理分包数据
      if (packet.Data.Data && packet.Data.Data.Buffer) {
        // 将base64转换为二进制数据
        const binaryData = base64ToBinary(packet.Data.Data.Buffer);
        
        // 验证接收到的数据长度
        console.log(`第${i+1}/${totalPackets}包: 预期长度=${expectedLength}, 实际接收=${binaryData.length}, 起始位置=${startPos}`);
        
        // 将数据复制到正确的位置
        completeImageData.set(binaryData, startPos);
        receivedLength += binaryData.length;
      }
    }
    
    // 验证接收到的总数据长度
    console.log(`图片下载完成: 预期总长度=${totalLen}, 实际接收总长度=${receivedLength}`);
    
    // 如果接收到的数据长度与预期不符，可能需要裁剪
    const finalImageData = receivedLength === totalLen ? 
      completeImageData : 
      completeImageData.slice(0, receivedLength);
    
    // 将二进制数据转换为base64
    const mergedBase64 = binaryToBase64(finalImageData);
    
    const mimeType = firstPacket.Data.MimeType || 'image/jpeg';
    // 添加data:image前缀
    const dataUri = `data:${mimeType};base64,${mergedBase64}`;
    
    // 通知下载完成
    if (statusCallback) {
      statusCallback('downloaded', dataUri);
    }
    
    // 返回数据URI
    return dataUri;
  } catch (error) {
    console.error('下载完整图片失败:', error);
    
    if (statusCallback) {
      statusCallback('failed', error);
    }
    
    throw error;
  }
};

/**
 * 上传朋友圈图片
 * @param {Array<string>} imageDataList - 图片的base64数据列表
 * @param {Array<string>} videoDataList - 视频数据列表，可选
 * @param {Function|null} statusCallback - 状态回调函数，用于通知上传状态
 * @returns {Promise<Object>} - 返回包含上传结果的Promise
 */
export const uploadFriendCircleImage = async (imageDataList, videoDataList = [], statusCallback = null) => {
  // 立即返回Promise，允许UI继续渲染
  return new Promise((resolve, reject) => {
    try {
      // 通知图片上传状态
      if (statusCallback) {
        statusCallback('uploading');
      }

      // 使用AbortController实现请求超时控制
      const controller = new AbortController();
      const timeoutId = setTimeout(() => {
        controller.abort();
      }, 10000); // 10秒超时限制，上传可能需要更长时间

      // 构建请求参数
      const requestParams = {
        ImageDataList: imageDataList,
        VideoDataList: videoDataList
      };

      // 执行异步请求
      (async () => {
        try {
          const response = await fetch(`${API_CONFIG.HOST}/sns/UploadFriendCircleImage?key=${API_CONFIG.KEY}`, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify(requestParams),
            signal: controller.signal // 添加AbortController信号
          });

          // 清除超时定时器
          clearTimeout(timeoutId);

          if (!response.ok) {
            throw new Error(`上传朋友圈图片失败: ${response.status} ${response.statusText}`);
          }

          const result = await response.json();

          // 验证响应数据
          if (!result || result.Code !== 200) {
            const errorMsg = result?.Text || '上传朋友圈图片失败';
            throw new Error(errorMsg);
          }

          // 上传成功，通知UI更新状态
          if (statusCallback) {
            statusCallback('uploaded', result);
          }

          resolve(result);
        } catch (error) {
          // 清除超时定时器
          clearTimeout(timeoutId);

          // 判断是否是超时错误
          if (error.name === 'AbortError') {
            const timeoutError = new Error('请求超时，上传朋友圈图片失败');
            console.error('上传朋友圈图片超时:', timeoutError);

            if (statusCallback) {
              statusCallback('failed', timeoutError);
            }

            reject(timeoutError);
          } else {
            console.error('上传朋友圈图片时出错:', error);

            if (statusCallback) {
              statusCallback('failed', error);
            }

            reject(error);
          }
        }
      })();
    } catch (outerError) {
      console.error('上传朋友圈图片过程中发生错误:', outerError);

      if (statusCallback) {
        statusCallback('failed', outerError);
      }

      reject(outerError);
    }
  });
};
